import datetime
import json
import logging

import hashlib
import time
import re
from django.core.cache import cache
from django.http import JsonResponse
import collections

import warnings
from decimal import Decimal
from comment.logcode import *
from utils.tokens import TIME_OUT

allow_active = ["login", "signin"]
salt = "JXU2NDkyJXU2MjUzJXU3Qjk3JXU2MjUz"


def server_time():
    return "%d" % int(time.time())


def response_change(response):
    response["Access-Control-Allow-Origin"] = "*"
    response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
    response["Access-Control-Max-Age"] = "1000"
    response["Access-Control-Allow-Headers"] = "*"
    response["Access-Control-Allow-Credentials"] = True
    return response


def err_resp(code, message):
    resp = dict()
    resp["code"] = code
    resp["message"] = message
    resp["data"] = None
    resp["server_time"] = server_time()
    resp["success"] = 0
    return response_change(JsonResponse(resp))


"""
token=c289f7ddb95675f7a2a87bd13c09c3a7&
time=1546779029&
salt=JXU2NDkyJXU2MjUzJXU3Qjk3JXU2MjUz&
params={"platform":"Google","remarks":"","pwuser":"test123","pwdata":"123456","user":"15299112b7ce4d988870a57e63c32efb"}&
apiName=create
"""


def check_token(params, uid, signature, time, api_name):
    body = {}
    token = cache.get(uid)
    if token is None:
        return False
    body["uid"] = cache.get(uid)
    body["salt"] = salt
    body["time"] = time
    body["params"] = params
    body["apiName"] = api_name
    body_str = ""
    body_list = sorted(body.items(), key=lambda x: x[0], reverse=True)
    for param in body_list:
        body_str += "{}={}&".format(param[0], str(param[1]))
    body_str = body_str[:-1]
    token = hashlib.sha256(body_str.encode()).hexdigest()
    print("body_str", body_str)
    print("token", token)
    if token == signature:
        # cache.set(uid, token, TIME_OUT)
        return True
    return False


def check_appinfo():
    pass


def check_time(timeDateStr):
    # time1 = datetime.datetime.strptime(timeDateStr, "%Y-%m-%d %H:%M:%S")
    #     # seconds = time.mktime(time1.timetuple())
    try:
        seconds = int(timeDateStr)
    except Exception as e:
        return -1
    # seconds = time.time()
    sub_time = (time.time() - seconds)
    if sub_time > 180000000:
        return None
    return seconds


def com_views(requests, func_map):
    body = None
    try:
        body = json.loads(requests.body.decode())
    except Exception as e:
        return err_resp(PARAMS_EMPTY, "format is not json")
    
    active = requests.GET.get("active")
    app_info = body.get("appInfo")
    time = body.get("time")
    time = check_time(time)
    if time is None:
        return err_resp(TIME_TOOLONG, "time is too long to get response")
    elif time == -1:
        return err_resp(TIME_TOOLONG, "time format is error")
    params = body.get("params")
    
    signature = body.get("signature")
    uid = body.get("uid")
    if not all([params, app_info, time, active]):
        return err_resp(PARAMS_EMPTY, "params is None")
    
    # 如果不在白名单中
    if not active in allow_active:
        
        if not all([signature, uid]):
            return err_resp(PARAMS_EMPTY, "params is None")
        
        if check_token(params, uid, signature, time, active) == False:
            return err_resp(LOGIN_ERROR, "signature is error")
    else:
        if cache.has_key(uid):
            cache.delete(uid)
    try:
        if isinstance(params, str):
            params = json.loads(params)
        elif isinstance(params, dict):
            pass
        else:
            return err_resp(PARAMS_EMPTY, "params format is not json")
    except Exception as e:
        logging.error(e)
        return err_resp(PARAMS_EMPTY, "params format is not json")
    
    func = func_map.get(active)
    if func==None:
        print(active)
        return err_response(701,"active is error")
    result = func(params)
    # try:
    #     result = func_map.get(active)(params)
    # except Exception as e:
    #     logging.error(e)
    #     return err_response(701)
    return result
    # if result:
    #     resp = dict(zip(["code", "message", "data", "success", "server_time"], result))
    #     return response_change(JsonResponse(resp))
    # else:
    #     return err_resp(PARAMS_ERROR, "active is empty")


def format_response(func):
    def response_change(request):
        response = func(request)
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
        response["Access-Control-Max-Age"] = "1000"
        response["Access-Control-Allow-Headers"] = "*"
        response["Access-Control-Allow-Credentials"] = True
        return response
    
    return response_change


def err_response(code, message=None):
    """
    错误请求响应
    :param code:
    :param message:
    :return:
    """
    if message is None:
        message = ERR_MSG.get(code)
    data = {"code": code, "message": message, "success": 0, "server_time": time.time(), "data": []}
    return JsonResponse(data)


def success_response(data=None):
    """
    成功请求响应
    :param data:
    :return:
    """
    data = {"code": 1, "message": "success", "success": 1, "data": data if not data is None else [],
            "server_time": time.time()}
    logging.info("success response: {}".format(str(data)))
    return JsonResponse(data)


def get_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]  # 这里是真实的ip
    else:
        ip = request.META.get('REMOTE_ADDR')  # 这里获得代理ip
    return ip


def clear_html_re(src_html):
    '''
    正则清除HTML标签
    :param src_html:原文本
    :return: 清除后的文本
    '''
    content = re.sub(r"</?(.+?)>", "", src_html)  # 去除标签
    content = re.sub(r"&nbsp;", " ", content)
    dst_html = re.sub(r"\s+", "", content)  # 去除空白字符
    return dst_html
